package com.pic.mgt.monitor.backup;

import java.io.File;
import java.io.IOException;

import com.pic.mgt.log.IgxLog;
import com.pic.mgt.monitor.WrongUnitFormatException;
import com.pic.mgt.monitor.parser.FormatParser;
import com.pic.mgt.unit.Business;
import com.pic.mgt.unit.Unit;
import com.pic.mgt.unit.operation.BusinessUnitOperation;
import com.pic.mgt.unit.operation.UnitOperationException;
import com.pic.mgt.utils.LogUtils;

public final class BusinessPhysicalBackup extends UnitPhysicalBackup {
	
	private FormatParser businessTargetFileParser;	
	private BusinessUnitOperation simpleBusinessUnitOperation;
	
	@Override
	public boolean backupUnit(Unit unit) {
		// 取得包含正確日期的備份路徑位置
		File backupPath = super.getBackupUnitPath();
		
		return backupUnit(unit, backupPath);
	}
	
	@Override
	public boolean backupUnit(Unit unit,
								  File backupDestFolder) {
		Business business = (Business)unit;
		
		boolean hasCompletedAction = true;
		
		// 開始備份實體檔案
		
		// 備份目標檔案
		try {
			// ********************** Log **********************
			if (IgxLog.messageLog.isDebugMode()) {
				IgxLog.messageLog.debug(this,
						"Backuping business '{}' target file '{}'.", business
								.getUnitName(), business.getTargetFilename());
			}
			// ********************** Log **********************
			
			simpleBusinessUnitOperation.copyTargetFile(
					business, backupDestFolder);
			
			// ********************** Log **********************
			if (IgxLog.messageLog.isDebugMode()) {
				IgxLog.messageLog.debug(this,
						"Backuping business '{}' target file '{}' completed.", business
								.getUnitName(), business.getTargetFilename());
			}
			// ********************** Log **********************
		} catch (UnitOperationException e1) {
			hasCompletedAction = false;
			
			// ********************** Log **********************
			IgxLog.messageLog.error(this,
					"SUDA-261 Backuping business '{}' target file '{}' failed.", business
							.getUnitName(), business.getTargetFilename());
			// ********************** Log **********************
		}
		
		// 備份確認檔案
		try {
			// ********************** Log **********************
			if (IgxLog.messageLog.isDebugMode()) {
				IgxLog.messageLog.debug(this,
						"Backuping business '{}' confirmation file '{}'.", business
								.getUnitName(),
								business.getConfirmationFilename());
			}
			// ********************** Log **********************
			
			simpleBusinessUnitOperation.copyConfirmationFile(
					business, backupDestFolder);
			
			// ********************** Log **********************
			if (IgxLog.messageLog.isDebugMode()) {
				IgxLog.messageLog.debug(this,
						"Backuping business '{}' confirmation file '{}' completed.", business
								.getUnitName(),
								business.getConfirmationFilename());
			}
			// ********************** Log **********************
		} catch (UnitOperationException e1) {
			hasCompletedAction = false;
			
			// ********************** Log **********************
			if (IgxLog.messageLog.isDebugMode()) {
				IgxLog.messageLog.debug(this,
						"Backuping business '{}' confirmation file '{}' failed.", business
								.getUnitName(),
								business.getConfirmationFilename());
			}
			// ********************** Log **********************
		}
		
		return hasCompletedAction;
	}
	
	@Override
	public boolean removeAndBackupErrorUnit(File confirmationFile) {
		boolean hasCompletedAction = true;
		
		// 取得包含正確日期的備份路徑位置
		File backupBadPath = getBackupBadUnitPath();
		
		// 開始搬移錯誤的實體檔案
		
		// 確認目標檔案是否存在，若不存在會拋出例外。
		try {
			// throws WrongUnitFormatException
			File targetFile = (File)
				businessTargetFileParser.parse(confirmationFile);
			
			// 搬移錯誤的目標檔案
			try {
				// ********************** Log **********************
				if (IgxLog.messageLog.isDebugMode()) {
					IgxLog.messageLog.debug(this,
							"Backuping wrong business: relative target file '{}'.",
							targetFile.getName());
				}
				// ********************** Log **********************
				
				// throws IOException
				simpleFileOperation.moveFileToFolder(targetFile, backupBadPath);
				
				// ********************** Log **********************
				if (IgxLog.messageLog.isDebugMode()) {
					IgxLog.messageLog.debug(this,
							"Backuping wrong business: relative target file '{}' completed.",
							targetFile.getName());
				}
				// ********************** Log **********************
			} catch (IOException e) {
				hasCompletedAction = false;
				
				// ********************** Log **********************
				LogUtils.error(this, IgxLog.messageDetailsLog, e);
				// ********************** Log **********************
				
				// ********************** Log **********************
				IgxLog.messageLog.error(this,
						"SUDA-262 Backuping wrong business: relative target file '{}' failed.",
						targetFile.getName());
				// ********************** Log **********************
			}
		} catch (WrongUnitFormatException e) {
			// 找不到對應的目標檔案，無須對目標檔案做搬移。
			
			// ********************** Log **********************
			if (IgxLog.messageLog.isDebugMode()) {
				IgxLog.messageLog.debug(this,
						"Backuping wrong business: no relative target file for confirmation file '{}'.",
						confirmationFile);
			}
			// ********************** Log **********************
		}
		
		// 搬移確認檔案
		try {
			// ********************** Log **********************
			if (IgxLog.messageLog.isDebugMode()) {
				IgxLog.messageLog.debug(this,
						"Backuping wrong business: confirmation file '{}'.",
						confirmationFile.getName());
			}
			// ********************** Log **********************
			
			// throws IOException
			simpleFileOperation.moveFileToFolder(confirmationFile, backupBadPath);
			
			// ********************** Log **********************
			if (IgxLog.messageLog.isDebugMode()) {
				IgxLog.messageLog.debug(this,
						"Backuping wrong business: confirmation file '{}' completed.",
						confirmationFile.getName());
			}
			// ********************** Log **********************
		} catch (IOException e) {
			hasCompletedAction = false;
			
			// ********************** Log **********************
			LogUtils.error(this, IgxLog.messageDetailsLog, e);
			// ********************** Log **********************

			// ********************** Log **********************
			IgxLog.messageLog.error(this,
					"SUDA-263 Backuping wrong business: confirmation file '{}' failed.",
					confirmationFile.getName());
			// ********************** Log **********************
		}
		
		return hasCompletedAction;
	}
	
	
	// --- getter and setter ---
	

	public void setBusinessTargetFileParser(FormatParser businessTargetFileParser) {
		this.businessTargetFileParser = businessTargetFileParser;
	}
	
	public void setSimpleBusinessUnitOperation(
			BusinessUnitOperation simpleBusinessUnitOperation) {
		this.simpleBusinessUnitOperation = simpleBusinessUnitOperation;
	}
}
